home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcr / pcr4_4.lha / DIST / loading / delete_symtab.c < prev    next >
C/C++ Source or Header  |  1989-04-03  |  8KB  |  308 lines

  1. /* begincopyright
  2.   Copyright (c) 1988 Xerox Corporation. All rights reserved.
  3.   Use and copying of this software and preparation of derivative works based
  4.   upon this software are permitted. Any distribution of this software or
  5.   derivative works must comply with all applicable United States export
  6.   control laws. This software is made available AS IS, and Xerox Corporation
  7.   makes no warranty about the software, its performance or its conformity to
  8.   any specification. Any person obtaining a copy of this software is requested
  9.   to send their name and post office or electronic mail address to:
  10.     PCR Coordinator
  11.     Xerox PARC
  12.     3333 Coyote Hill Rd.
  13.     Palo Alto, CA
  14.   endcopyright */
  15. #include <sys/types.h>
  16. #include <sys/file.h>
  17. #include <sys/stat.h>
  18. #include <stdio.h>
  19. #include <a.out.h>
  20. #include <errno.h>
  21.  
  22. /*
  23.  *  Needed by regexp.
  24.  */
  25. #define INIT register char *regexpp = instring;
  26. #define GETC() (*regexpp++)
  27. #define PEEKC() (*regexpp)
  28. #define UNGETC(c) (--regexpp)
  29. #define RETURN(pointer) return;
  30. #define ERROR(val) regerr(val)
  31.  
  32. #include <regexp.h>
  33.  
  34.  
  35. #ifdef sparc
  36. #define r_symbolnum r_index
  37. #define relocation_info reloc_info_sparc
  38. #endif
  39.  
  40. #define CLEAN(var) {if (var) {free(var); var = 0;}}
  41.  
  42. static int file_length;/* length of input file in bytes */
  43. static FILE *file;     /* input file                    */
  44.  
  45. struct exec header;    
  46. struct nlist *symtab;
  47. caddr_t stringtab;
  48. int num_symbols;
  49. long string_len;
  50. unsigned long num_reloc_data_items, num_reloc_text_items;
  51. struct relocation_info *data_reloctab, *text_reloctab;/* relocation table */
  52. unsigned long num_reloc_data_items_kept, num_reloc_text_items_kept;
  53.  
  54. #define INCN 100000
  55. static int maxn = 0;
  56. static int nextn = 0;
  57. static int *saven = 0;
  58.  
  59. #define MAXCOMPILEDREGSIZE 1000
  60. char expbuf[MAXCOMPILEDREGSIZE];
  61.  
  62. char *current_file;
  63.  
  64. compare_n(a, b)
  65. int *a, *b;
  66. {
  67.   return(*a - *b);
  68. }
  69.  
  70. /*
  71.  *  Main program for 'delete_symtab'.
  72.  */
  73. main(argc, argv)
  74.      char **argv;
  75. {
  76.   
  77.   /* process arguments */
  78.   if (argc < 3) {
  79.     printf("Usage: %s  regexp filename[s].\n\tRemoves any symbols which match the regular expression.\n", argv[0]);
  80.     exit(1);
  81.   };
  82.   argc--; argv++;
  83.   compile(*argv, expbuf, &expbuf[MAXCOMPILEDREGSIZE], '\0');
  84.   for (; --argc > 0;) {
  85.     simplify_file(*++argv);
  86.   }
  87.   exit(0);
  88. }
  89.   
  90. simplify_file(onefilename)
  91.      char *onefilename;
  92. {
  93.   int i, n_i;
  94.  
  95.   printf("Deleting syms in %s.\n", onefilename);
  96.   current_file = onefilename;  /* for error messages */
  97.  
  98.   /*
  99.    *  Initialize.
  100.    */
  101.   maxn = 0;
  102.   nextn = 0;
  103.   CLEAN(saven);
  104.   CLEAN(symtab);
  105.   CLEAN(data_reloctab);
  106.   CLEAN(text_reloctab);
  107.   CLEAN(stringtab);
  108.  
  109.   /*
  110.    *    Open the file:  don't return if unopened.
  111.    */
  112.   open_file(onefilename);
  113.  
  114.   /* 
  115.    *  Look for symbols that don't match the regexp.  Remember them.
  116.    */
  117.   for(i=0; i < num_symbols; i++ ) {
  118.     if ( ! step(symtab[i].n_un.n_strx + stringtab, expbuf)) {
  119.       remember_n(i);
  120.     } else {
  121.       i = i;  /* someplace to put a breakpoint */
  122.     }
  123.   }
  124.  
  125.   /*
  126.    *  Start point for writing new file information.
  127.    */
  128.   fseek(file, N_TRELOFF(header), 0);
  129.  
  130.   /*
  131.    *  Write out text relocation information, adjusted to new symbol locations.
  132.    */
  133.   num_reloc_text_items_kept = 0;
  134.   for (i=0; i < num_reloc_text_items; i++) {
  135.     if (text_reloctab[i].r_extern && (n_i = n_p(text_reloctab[i].r_symbolnum)) == -1) {
  136.       i = i;   /* a place to put breakpoints */
  137.     } else {
  138.       if (text_reloctab[i].r_extern) {
  139.     text_reloctab[i].r_symbolnum = n_i;
  140.       }
  141.       fwrite(&text_reloctab[i], sizeof(struct relocation_info), 1, file);
  142.       num_reloc_text_items_kept += 1;
  143.     }
  144.   }
  145.   /*
  146.    *  Write out data relocation information that points to saved symbols only.
  147.    */
  148.   num_reloc_data_items_kept = 0;
  149.   for (i=0; i < num_reloc_data_items; i++) {
  150.     if (data_reloctab[i].r_extern && (n_i = n_p(data_reloctab[i].r_symbolnum)) == -1) {
  151.       i = i;   /* a place to put breakpoints */
  152.     } else {
  153.       if (data_reloctab[i].r_extern) {
  154.     data_reloctab[i].r_symbolnum = n_i;
  155.       }
  156.       fwrite(&data_reloctab[i], sizeof(struct relocation_info), 1, file);
  157.       num_reloc_data_items_kept += 1;
  158.     }
  159.   }
  160.  
  161.   /* 
  162.    *  Write out symbols that did not have nstabs bit set.
  163.    *  by  copying them in place on top of other symbols.
  164.    */
  165.   for(i=0; i < nextn; i++ ) {
  166.     fwrite(&symtab[saven[i]], sizeof(struct nlist), 1, file);
  167.   }
  168.  
  169.   /*
  170.    *  Write out the same old stringtab (now in a new place in the file).
  171.    *  (Someday the stringtab could also be shrunk.)
  172.    */
  173.   fwrite(stringtab, string_len, 1, file);
  174.  
  175.   /*
  176.    *  Update the header, and write it out.
  177.    */
  178.   header.a_syms = sizeof(struct nlist)*nextn;
  179.   header.a_drsize = sizeof(struct relocation_info)*num_reloc_data_items_kept;
  180.   header.a_trsize = sizeof(struct relocation_info)*num_reloc_text_items_kept;
  181.   fseek(file, (long)0, 0);
  182.   fwrite(&header, sizeof(struct exec), 1, file);
  183.  
  184.   fflush(file);
  185.   ftruncate(fileno(file), file_length - (num_symbols-nextn)*sizeof(struct nlist));
  186.  
  187.   /* done with this file */
  188.   fclose(file);
  189. }
  190.  
  191. open_file(filename)
  192. char *filename;
  193. {
  194.   struct stat the_stat_buffer;
  195.   /*
  196.    *    Open the file:  don't return if unopened.
  197.    */
  198.   if ((file = fopen(filename, "r+")) == NULL) {
  199.     char temp[128];
  200.     sprintf(temp, "Cannot open file '%s'.", filename);
  201.     error(temp); /* never returns */
  202.   }
  203.   
  204.   /* get the file size */
  205.   fstat(fileno(file), &the_stat_buffer);
  206.   file_length = the_stat_buffer.st_size;
  207.   
  208.   fseek(file, (long)0, 0);
  209.   fread (&header, sizeof(struct exec), 1, file);
  210.   if (N_BADMAG(header)) {
  211.     error("Bad magic number."); /* never returns */
  212.   }
  213.  
  214.   num_reloc_text_items = (header.a_trsize / sizeof (struct relocation_info));
  215.   num_reloc_data_items = (header.a_drsize / sizeof (struct relocation_info));
  216.   
  217.   if (num_reloc_text_items > 0) {
  218.     text_reloctab = (struct relocation_info *)malloc(sizeof(struct relocation_info)*num_reloc_text_items);
  219.     fseek(file, N_TRELOFF(header), 0);
  220.     fread (text_reloctab, sizeof (struct relocation_info), num_reloc_text_items, file);
  221.   }
  222.  
  223.   if (num_reloc_data_items > 0) {
  224.     data_reloctab = (struct relocation_info *)malloc(sizeof(struct relocation_info)*num_reloc_data_items);
  225.     fseek(file, N_DRELOFF(header), 0);
  226.     fread (data_reloctab, sizeof (struct relocation_info), num_reloc_data_items, file);
  227.   }
  228.  
  229.   /*
  230.    *    Read in the symbol table
  231.    */
  232.   num_symbols = header.a_syms / (sizeof (struct nlist));
  233.   if (num_symbols <= 0) {
  234.     error("No symbol table."); /* never returns */
  235.   }
  236.   symtab= (struct nlist *) malloc (header.a_syms);
  237.   fseek(file, N_SYMOFF(header), 0);
  238.   fread (symtab, sizeof (struct nlist), num_symbols, file);
  239.  
  240.   /*
  241.    *    Read in the string table
  242.    */
  243.   {
  244.     string_len = (file_length - N_STROFF(header));
  245.     if (string_len <= 0) {    
  246.       error("No string table."); /* never returns */
  247.     }
  248.     stringtab = (caddr_t) malloc (string_len);
  249.     fseek(file, N_STROFF(header), 0);
  250.     fread (stringtab, 1, string_len, file);
  251.   }
  252. }
  253.  
  254. error(s)
  255. char *s;
  256. {
  257.   printf("simplify_symtab error: %s, in file '%s'\n", s, current_file);
  258.   exit(1);
  259. }
  260.  
  261. remember_n(n)
  262. int n;
  263. {
  264.   if (nextn >= maxn) {
  265.     /* need more storage */
  266.     maxn += INCN;
  267.     if (saven) {
  268.       saven = (int *)realloc(saven, maxn*sizeof(int));
  269.     } else {
  270.       saven = (int *)malloc(maxn*sizeof(int));
  271.     }
  272.   }
  273.   saven[nextn++] = n;
  274. }
  275.  
  276. n_p(n)
  277. int n;
  278. {
  279.   int *retval;
  280.   retval = (int *)bsearch(&n, saven, nextn, sizeof(int), compare_n);
  281.   if (retval == 0) {
  282.     return -1;
  283.   } else {
  284.     return ((long)retval - (long)saven)/sizeof(int);
  285.   }
  286. }
  287.  
  288. regerr(val)
  289. {
  290.   char *s;
  291.   printf("delete_symtab: Error in regular expression.");
  292.   switch(val) {
  293.     case 11: s =   "Range endpoint too large."; break;
  294.     case 16: s = "Bad number."; break;
  295.     case 25: s = "``\ digit'' out of range."; break;
  296.     case 36: s = "Illegal or missing delimiter."; break;
  297.     case 41: s = "No remembered search string."; break;
  298.     case 42: s = "\( \) imbalance."; break;
  299.     case 43: s = "Too many \(."; break;
  300.     case 44: s = "More than 2 numbers  given  in \{ \}."; break;
  301.     case 45: s = "} expected after \."; break;
  302.     case 46: s = "First number exceeds second in \{ \}."; break;
  303.     case 49: s = "[] imbalance."; break;
  304.     case 50: s = "Regular expression too long."; break;
  305.     }
  306.   exit(1);
  307. }
  308.